/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package group6renderer;

import group6renderer.renderernode.*;
import java.util.ArrayList;

/**
 *
 * @author jonnie,Yiannis
 */
public class Parser
{

    private int cursor;
    private int lineNo;
    private String theHTML;
    private TreeNode tree;
    private TreeNode currentNode;
    private ArrayList<String> openTags = new ArrayList<String>();
    private int tagCounter;
    
    public Parser(String theHTML)
    {
	this.theHTML = theHTML;
   
    
    }

    private char getChar() throws Exception
    {
    	if (cursor == theHTML.length())
    	{
    		throw new Exception("EOF");
    	}
    	char curChar = theHTML.charAt(cursor);
    	while (Character.getType(curChar) == Character.LINE_SEPARATOR)
    	{
    		System.out.println("charjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
    		lineNo++;
    		cursor++;
    		curChar = theHTML.charAt(cursor);
    	}
    return curChar;
    }

    
    private String parseText(boolean incSpaces)
    {
    	StringBuffer theText = new StringBuffer();
    	try
    	{ 
    		System.out.println("ready to get the name of the tag");
//    		while (cursor<theHTML.length() &&( Character.isLetterOrDigit(getChar()) || (Character.isSpaceChar(getChar()) && incSpaces)))
  
    		while (cursor<theHTML.length() &&( getChar()!='>' && getChar()!='<' || (Character.isSpaceChar(getChar()) && incSpaces)))

    		{
    			theText.append(getChar());
    			cursor++;
    			//System.out.println("mesa sto while");
    		}
    		System.out.println(theText);
    	}
    	catch (Exception ex)
    	{
	    System.out.println("telos tou file");
    	}
    return theText.toString();
    }

    
    private void parseTextNode()
    {
    	System.out.println("parsing text");
    
    	
    	
    	currentNode.addChild(new TextNode(parseText(true)));
    
    
    }

    private void parseTag()
    {
    	TreeNode newNode = null;
    	cursor++;
    	try
    	{
    		if (!Character.toString(getChar()).equals("/"))
    		{
    			try
    			{
    				newNode = HTMLConstants.getInstance(parseText(false));
        			tagCounter++;
    				if (tagCounter==1)
    					{tree=newNode; currentNode=newNode;}
    				
    				else
    				{	
    					newNode.setParent(currentNode);
        				currentNode.addChild(newNode);
        				if (!newNode.isLeaf())
        				{currentNode = newNode;openTags.add(currentNode.getName());}
    				}
    			}
    			catch(Exception e) {System.out.printf("tag not founnd");}
    			
    		}
    		else
    		{
    			
    			cursor++;
    			//System.out.println("char -> "+theHTML.charAt(cursor));
    			String tagName = parseText(false);
    			if (openTags.contains(tagName))
    				currentNode= closeTag(currentNode,new ArrayList<TreeNode>(),tagName);
    			
    		}
    	}
    	catch (Exception ex)
    	{
    		System.out.println(ex.toString());
    	}
    	cursor++;
    } 


    
    public TreeNode parse()
    {
     while(cursor < theHTML.length())
     {
    	
    	try
    	{
    		if (Character.toString(getChar()).equals("<"))
    		{
    			parseTag();
    		}
    		else
    		{
    			parseTextNode();
    		}
    	}
    	catch (Exception ex)
    	{
    		System.out.println(ex.toString());
    		return null;
    	}
     }
     return tree;
    }

   
   private TreeNode closeTag(TreeNode theNode,ArrayList<TreeNode> unClosedTags,String tagName)
    {
	TreeNode lastUnclosed;
	 
	System.out.println("close -> "+theHTML.charAt(cursor));
	if (theNode==tree)
		return tree;
	
		TreeNode parent = theNode.parent;
    	if (theNode.getName().equalsIgnoreCase(tagName))
    	{
    		
    		openTags.remove(theNode.getName());
    		parent = theNode.parent;
    		while (!unClosedTags.isEmpty())
    		{
    			lastUnclosed = unClosedTags.remove(unClosedTags.size() - 1);
    			parent.addChild(lastUnclosed);
    			lastUnclosed.setParent(parent);
    			 parent=lastUnclosed;
    		}
    	}
    	else
    	{
    		unClosedTags.add(theNode.copy());
    		parent = closeTag(parent,unClosedTags,tagName);
    	}
	//cursor++;
//	System.out.println("char -> "+theHTML.charAt(cursor));
    return parent;    	
    }
}
